﻿using CNative.Dapper.Utils;
using CNative.WebApi.Common.Models;
using CNative.WebApi.Utils;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.ServiceModel;
using System.Web;

namespace CNative.DBWebApi.DBBaseRule
{ 
    /// <summary>
    /// 
    /// </summary>
    public interface IDbDBSqlRule : IDisposable
    {
        /// <summary>
        /// 执行脚本
        /// </summary>
        /// <param name="_eSql"></param>
        /// <returns></returns>
        bool Execute(DBSqlEntity _eSql);
        /// <summary>
        /// 批量执行脚本
        /// </summary>
        /// <param name="_StrSqlList"></param>
        /// <returns></returns>
        bool ExecuteList(List<DBSqlEntity> _StrSqlList);
        /// <summary>
        /// 查寻返回DataSet
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        DataSet QueryDataSet(DBSqlEntity sql);
        /// <summary>
        /// 查寻返回DataTable
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        DataTable QueryDataTable(DBSqlEntity sql);
        /// <summary>
        /// 查寻返回实体集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <returns></returns>
        List<T> Query<T>(DBSqlEntity sql) where T : class;
        /// <summary>
        /// 查寻返回单行实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <returns></returns>
        T QuerySingle<T>(DBSqlEntity sql) where T : class;
        /// <summary>
        /// 查寻返回单个字段值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <returns></returns>
        T GetSingle<T>(DBSqlEntity sql);
    }
    /// <summary>
    /// sql脚本
    /// </summary>
    public class DBSqlRule : IDbDBSqlRule
    {
        /// <summary>
        /// 
        /// </summary>
        public DBSqlRule()
        {
        }
        SqlEntity CreateSqlEntity(IDbHelper dbPub, DBSqlEntity _eSql)
        {
            if (dbPub.IsNullOrEmpty() || _eSql.IsNullOrEmpty() || _eSql.Sql.IsNullOrEmpty())
                return null;
            var sql = dbPub.CreateSqlEntity(_eSql.Sql);
            if (_eSql.Parameter.IsNotNullOrEmpty() && _eSql.Parameter.NullToStr().Length > 0)
                sql.Parameter = _eSql.Parameter;
            else
                sql.Parameter = null;
            sql.CommandType = (CommandType)_eSql.CommandType;
            sql.CommandTimeout = _eSql.CommandTimeout;

            LogUtil.Debug("DBName=" + dbPub.DBName+",sql=" +sql.Sql);
            return sql;
        }
        List<SqlEntity> CreateSqlEntity(IDbHelper dbPub, List<DBSqlEntity> _eSqls)
        {
            if (dbPub.IsNullOrEmpty() || _eSqls.IsNullOrEmpty_())
                return null;
            List<SqlEntity> sqlEntities = new List<SqlEntity>();
            _eSqls.ForEach(_eSql =>
            {
                if (_eSql.Sql.IsNullOrEmpty())
                    return;
                var sql = dbPub.CreateSqlEntity(_eSql.Sql);
                if (_eSql.Parameter.IsNotNullOrEmpty() && _eSql.Parameter.NullToStr().Length > 0)
                    sql.Parameter = _eSql.Parameter;
                else
                    sql.Parameter = null;
                sql.CommandType = (CommandType)_eSql.CommandType;
                sql.CommandTimeout = _eSql.CommandTimeout;

                LogUtil.Debug("DBName=" + dbPub.DBName + ",sql=" + sql.Sql);

                sqlEntities.Add(sql);
            });

            return sqlEntities;
        }
        /// <summary>
        /// 执行脚本
        /// </summary>
        /// <param name="_eSql"></param>
        /// <returns></returns>
        public bool Execute(DBSqlEntity _eSql)
        {
            if (_eSql.IsNullOrEmpty() || _eSql.Sql.IsNullOrEmpty())
                return false;
            if (_eSql.DBName.IsNullOrEmpty_()) _eSql.DBName = "BaseDb";

            var dbPub = new DbHelper(_eSql.DBName);
            var sql = CreateSqlEntity(dbPub, _eSql);

            return dbPub.Execute(sql);
        }
        /// <summary>
        /// 批量执行脚本
        /// </summary>
        /// <param name="_StrSqlList"></param>
        /// <returns></returns>
        public bool ExecuteList(List<DBSqlEntity> _StrSqlList)
        {
            if (_StrSqlList.IsNullOrEmpty_())
                return false;
            if (_StrSqlList[0].DBName.IsNullOrEmpty_()) _StrSqlList[0].DBName = "BaseDb";

            var dbPub = new DbHelper(_StrSqlList[0].DBName);
            var sql = CreateSqlEntity(dbPub, _StrSqlList);
            if (sql.IsNullOrEmpty_())
                return false;
            return dbPub.Execute(sql);
        }
        /// <summary>
        /// 查寻返回DataSet
        /// </summary>
        /// <param name="_eSql"></param>
        /// <returns></returns>
        public DataSet QueryDataSet(DBSqlEntity _eSql)
        {
            if (_eSql.IsNullOrEmpty() || _eSql.Sql.IsNullOrEmpty())
                return null;
            if (_eSql.DBName.IsNullOrEmpty_()) _eSql.DBName = "BaseDb";

            var dbPub = new DbHelper(_eSql.DBName);
            var sql = CreateSqlEntity(dbPub, _eSql);

            return dbPub.QueryDataSet(sql);
        }
        /// <summary>
        /// 查寻返回DataTable
        /// </summary>
        /// <param name="_eSql"></param>
        /// <returns></returns>
        public DataTable QueryDataTable(DBSqlEntity _eSql)
        {
            if (_eSql.IsNullOrEmpty() || _eSql.Sql.IsNullOrEmpty())
                return null;
            if (_eSql.DBName.IsNullOrEmpty_()) _eSql.DBName = "BaseDb";

            var dbPub = new DbHelper(_eSql.DBName);
            var sql = CreateSqlEntity(dbPub, _eSql);

            var dt = dbPub.QueryDataTable(sql);
            if (dt.TableName.IsNullOrEmpty()) dt.TableName = "Table";
            return dt;
        }
        /// <summary>
        /// 查寻返回实体集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_eSql"></param>
        /// <returns></returns>
        public List<T> Query<T>(DBSqlEntity _eSql) where T : class
        {
            if (_eSql.IsNullOrEmpty() || _eSql.Sql.IsNullOrEmpty())
                return null;
            if (_eSql.DBName.IsNullOrEmpty_()) _eSql.DBName = "BaseDb";

            var dbPub = new DbHelper(_eSql.DBName);
            var sql = CreateSqlEntity(dbPub, _eSql);

            return dbPub.Query<T>(sql);
        }
        /// <summary>
        /// 查寻返回单行实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_eSql"></param>
        /// <returns></returns>
        public T QuerySingle<T>(DBSqlEntity _eSql) where T : class
        {
            if (_eSql.IsNullOrEmpty() || _eSql.Sql.IsNullOrEmpty())
                return null;
            if (_eSql.DBName.IsNullOrEmpty_()) _eSql.DBName = "BaseDb";

            var dbPub = new DbHelper(_eSql.DBName);
            var sql = CreateSqlEntity(dbPub, _eSql);

            return dbPub.QuerySingle<T>(sql);
        }
        /// <summary>
        /// 查寻返回单个字段值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_eSql"></param>
        /// <returns></returns>
        public T GetSingle<T>(DBSqlEntity _eSql)
        {
            if (_eSql.IsNullOrEmpty() || _eSql.Sql.IsNullOrEmpty())
                return default(T);
            if (_eSql.DBName.IsNullOrEmpty_()) _eSql.DBName = "BaseDb";

            var dbPub = new DbHelper(_eSql.DBName);
            var sql = CreateSqlEntity(dbPub, _eSql);

            return dbPub.GetSingle<T>(sql);
        }

        #region Dispose
        /// <summary>
        /// 标记DbContext是否已经释放
        /// </summary>
        protected bool IsDisposed { get; set; }
        /// <summary>
        /// 释放数据,初始化状态
        /// </summary>
        public void Dispose()
        {
            IsDisposed = true;
        }
        #endregion
    }
}